home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / umoria / save.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-07-28  |  15.6 KB  |  536 lines

  1. #include <stdio.h>
  2. #include <sys/types.h>
  3. #include <sys/stat.h>
  4.  
  5. #include "constants.h"
  6. #include "config.h"
  7. #include "types.h"
  8. #include "externs.h"
  9.  
  10. #ifdef USG
  11. #include <string.h>
  12. #else
  13. #include <strings.h>
  14. #endif
  15.  
  16. #ifdef sun   /* correct SUN stupidity in the stdio.h file */
  17. char *sprintf();
  18. #endif
  19.  
  20. #ifdef ultrix
  21. void sleep();
  22. #endif
  23.  
  24. #ifdef USG
  25. unsigned sleep();
  26. #endif
  27.  
  28. #define IREAD 00400
  29. #define IWRITE 00200
  30.  
  31. /* This save package was brought to by            -JWT-
  32.    and                                                  -RAK-
  33.    and has been completely rewritten for UNIX by        -JEW-  */
  34.  
  35. /* Wizard command for restoring character        -RAK-    */
  36. restore_char()
  37. {
  38.   vtype fnam;
  39.   register int i, j;
  40.   register FILE *f1;
  41.   int error;
  42.   vtype temp;
  43.   double version;
  44.   struct stat buf2;
  45.   char char_tmp;
  46.   char char_tmp_array[3];
  47.   register cave_type *c_ptr;
  48.  
  49.   clear_screen(0, 0);
  50.  
  51.   prt("Enter Filename:", 0, 0);
  52.   if (!get_string(fnam, 0, 16, 60))
  53.     {
  54.       return(FALSE);
  55.     }
  56.   no_controlz();
  57.  
  58.   if (chmod(fnam, (IREAD | IWRITE)) == -1)
  59.     {
  60.       (void) sprintf(temp, "Can not change file mode for %s", fnam);
  61.       prt(temp, 0, 0);
  62.     }
  63.  
  64.   if ((f1 = fopen(fnam, "r")) == NULL)
  65.     {
  66.       (void) sprintf(temp, "Cannot open file %s for reading.", fnam);
  67.       prt(temp, 0, 0);
  68.       return(FALSE);
  69.     }
  70.  
  71.   prt("Restoring Character...", 0, 0);
  72.   put_qio();
  73.   error = 0;
  74.   error |= !fread((char *)&version, sizeof(version), 1, f1);
  75.   error |= !fread((char *)&py, sizeof(py), 1, f1);
  76.   error |= !fread((char *)&char_row, sizeof(char_row), 1, f1);
  77.   error |= !fread((char *)&char_col, sizeof(char_col), 1, f1);
  78.   error |= !fread((char *)&inven_ctr, sizeof(inven_ctr), 1, f1);
  79.   error |= !fread((char *)&inven_weight, sizeof(inven_weight), 1, f1);
  80.   error |= !fread((char *)&equip_ctr, sizeof(equip_ctr), 1, f1);
  81.   error |= !fread((char *)&dun_level, sizeof(dun_level), 1, f1);
  82.   error |= !fread((char *)&missile_ctr, sizeof(missile_ctr), 1, f1);
  83.   error |= !fread((char *)&mon_tot_mult, sizeof(mon_tot_mult), 1, f1);
  84.   error |= !fread((char *)&turn, sizeof(turn), 1, f1);
  85.   error |= !fread((char *)inventory, sizeof(inventory), 1, f1);
  86.   error |= !fread((char *)magic_spell[py.misc.pclass],
  87.           sizeof(spell_type), 31, f1);
  88.   error |= !fread((char *)&cur_height, sizeof(cur_height), 1, f1);
  89.   error |= !fread((char *)&cur_width, sizeof(cur_width), 1, f1);
  90.   error |= !fread((char *)&max_panel_rows, sizeof(max_panel_rows), 1, f1);
  91.   error |= !fread((char *)&max_panel_cols, sizeof(max_panel_cols), 1, f1);
  92.  
  93.   for (i = 0; i < MAX_HEIGHT; i++)
  94.     for (j = 0; j < MAX_WIDTH; j++)
  95.       {
  96.     c_ptr = &cave[i][j];
  97.     error |= !fread((char *)&c_ptr->cptr, sizeof(c_ptr->cptr), 1, f1);
  98.     error |= !fread((char *)&c_ptr->tptr, sizeof(c_ptr->tptr), 1, f1);
  99.     error |= !fread((char *)&char_tmp, sizeof(char_tmp), 1, f1);
  100.     c_ptr->fval = char_tmp & 0xF;
  101.     c_ptr->fopen = (char_tmp >> 4) & 0x1;
  102.     c_ptr->fm = (char_tmp >> 5) & 0x1;
  103.     c_ptr->pl = (char_tmp >> 6) & 0x1;
  104.     c_ptr->tl = (char_tmp >> 7) & 0x1;
  105.       }
  106.  
  107.   error |= !fread((char *)t_list, sizeof(t_list), 1, f1);
  108.   error |= !fread((char *)&tcptr, sizeof(tcptr), 1, f1);
  109.   error |= !fread((char *)object_ident, sizeof(object_ident), 1, f1);
  110.   error |= !fread((char *)m_list, sizeof(m_list), 1, f1);
  111.   error |= !fread((char *)&mfptr, sizeof(mfptr), 1, f1);
  112.   error |= !fread((char *)&muptr, sizeof(muptr), 1, f1);
  113.  
  114.   if (version == 4.83)
  115.     {
  116.       /* insult_cur was a byte in 4.83, but is now a short */
  117.       for (i = 0; i < MAX_STORES; i++)
  118.     {
  119.       error |= !fread((char *)&store[i].store_open,
  120.              sizeof(short), 1, f1);
  121.       error |= !fread((char *)&char_tmp,
  122.              sizeof(char), 1, f1);   /* this is different */
  123.           store[i].insult_cur = (short)char_tmp;
  124.       error |= !fread((char *)&store[i].owner,
  125.              sizeof(char), 1, f1);
  126.       error |= !fread((char *)&store[i].store_ctr,
  127.              sizeof(char), 1, f1);
  128.           /* quick compatibility hack for a local vax */
  129.           /* ignore three bytes of fill character */
  130.       error |= !fread((char *)char_tmp_array,
  131.              sizeof(char), 3, f1);
  132.       error |= !fread((char *)store[i].store_inven,
  133.              sizeof(inven_record), STORE_INVEN_MAX, f1);
  134.     }
  135.     }
  136.   else
  137.     {
  138.       error |= !fread((char *)store, sizeof(store), 1, f1);
  139.     }
  140.  
  141.   error |= !fread((char *)&buf2, sizeof(buf2), 1, f1);
  142.  
  143.   error |= !fread((char *)norm_state, sizeof(norm_state), 1, f1);
  144.   error |= !fread((char *)randes_state, sizeof(randes_state), 1, f1);
  145.   error |= !fread((char *)&randes_seed, sizeof(randes_seed), 1, f1);
  146.   error |= !fread((char *)town_state, sizeof(town_state), 1, f1);
  147.   error |= !fread((char *)&town_seed, sizeof(town_seed), 1, f1);
  148.  
  149.   if (version >= 4.87)
  150.     {
  151.       error |= !fread((char *)&panic_save, sizeof(panic_save), 1, f1);
  152.       /* clear the panic_save condition, which is used to indicate 
  153.      cheating */
  154.       panic_save = 0;
  155.     }
  156.  
  157.   error |= fclose(f1);
  158.  
  159.   controlz();
  160.  
  161.   if (error)
  162.     {
  163.       (void) sprintf(temp, "Error reading in file %s", fnam);
  164.       prt(temp, 0, 0);
  165.       return(FALSE);
  166.     }
  167.   if (unlink(fnam) == -1)
  168.     {
  169.       (void) sprintf(temp, "Cannot delete file %s", fnam);
  170.       prt(temp, 0, 0);
  171.     }
  172.  
  173.   /* reidentify objects */
  174.   /* very inefficient, should write new routine perhaps? */
  175.   for (i = 0; i < MAX_OBJECTS; i++)
  176.     if (object_ident[i] == TRUE)
  177.       identify(object_list[i]);
  178.  
  179.   return(FALSE);
  180. }
  181.  
  182.  
  183. save_char(exit, no_ask)
  184. int exit;
  185. int no_ask;
  186. {
  187.   register int i, j;
  188.   int flag;
  189.   int error;
  190.   vtype fnam, temp;
  191.   double version;
  192.   struct stat buf;
  193.   register FILE *f1;
  194.   char char_tmp;
  195.   register cave_type *c_ptr;
  196.  
  197.   flag = FALSE;
  198.  
  199.   if (!no_ask)
  200.     {
  201.       prt("Enter Filename:", 0, 0);
  202.       if (!get_string(fnam, 0, 16, 60))
  203.     {
  204.       /* only return if exit TRUE, i.e. this is not a panic save */
  205.       if (exit)
  206.         return;
  207.       else
  208.         (void) strcpy(fnam, "MORIACHR.SAV");
  209.     }
  210.       /* if get_string succeeded, but returned zero length */
  211.       else if (strlen(fnam) == 0)
  212.     (void) strcpy(fnam, "MORIACHR.SAV");
  213.     }
  214.   else
  215.     (void) strcpy(fnam, "MORIACHR.SAV");
  216.  
  217.   no_controlz();
  218.  
  219.   /* Open the user's save file                             -JEW-   */
  220.   if ((f1 = fopen(fnam, "w")) == NULL)
  221.     {
  222.       (void) sprintf(temp, "Error creating %s", fnam);
  223.       msg_print(temp);
  224.       return;
  225.     }
  226.   flag = TRUE;
  227.   clear_screen(0, 0);
  228.   prt("Saving character...", 0, 0);
  229.   put_qio();
  230.   version = CUR_VERSION;
  231.   error = 0;
  232.   error |= !fwrite((char *)&version, sizeof(version), 1, f1);
  233.   error |= !fwrite((char *)&py, sizeof(py), 1, f1);
  234.   error |= !fwrite((char *)&char_row, sizeof(char_row), 1, f1);
  235.   error |= !fwrite((char *)&char_col, sizeof(char_col), 1, f1);
  236.   error |= !fwrite((char *)&inven_ctr, sizeof(inven_ctr), 1, f1);
  237.   error |= !fwrite((char *)&inven_weight, sizeof(inven_weight), 1, f1);
  238.   error |= !fwrite((char *)&equip_ctr, sizeof(equip_ctr), 1, f1);
  239.   error |= !fwrite((char *)&dun_level, sizeof(dun_level), 1, f1);
  240.   error |= !fwrite((char *)&missile_ctr, sizeof(missile_ctr), 1, f1);
  241.   error |= !fwrite((char *)&mon_tot_mult, sizeof(mon_tot_mult), 1, f1);
  242.   error |= !fwrite((char *)&turn, sizeof(turn), 1, f1);
  243.   error |= !fwrite((char *)inventory, sizeof(inventory), 1, f1);
  244.   error |= !fwrite((char *)magic_spell[py.misc.pclass],
  245.            sizeof(spell_type), 31, f1);
  246.   error |= !fwrite((char *)&cur_height, sizeof(cur_height), 1, f1);
  247.   error |= !fwrite((char *)&cur_width, sizeof(cur_width), 1, f1);
  248.   error |= !fwrite((char *)&max_panel_rows, sizeof(max_panel_rows), 1, f1);
  249.   error |= !fwrite((char *)&max_panel_cols, sizeof(max_panel_cols), 1, f1);
  250.  
  251.   for (i = 0; i < MAX_HEIGHT; i++)
  252.     for (j = 0; j < MAX_WIDTH; j++)
  253.       {
  254.     c_ptr = &cave[i][j];
  255.     char_tmp = c_ptr->fval | (c_ptr->fopen << 4) | (c_ptr->fm << 5) |
  256.       (c_ptr->pl << 6) | (c_ptr->tl << 7);
  257.     error |= !fwrite((char *)&c_ptr->cptr, sizeof(c_ptr->cptr), 1, f1);
  258.     error |= !fwrite((char *)&c_ptr->tptr, sizeof(c_ptr->tptr), 1, f1);
  259.     error |= !fwrite((char *)&char_tmp, sizeof(char_tmp), 1, f1);
  260.       }
  261.  
  262.   error |= !fwrite((char *)t_list, sizeof(t_list), 1, f1);
  263.   error |= !fwrite((char *)&tcptr, sizeof(tcptr), 1, f1);
  264.   error |= !fwrite((char *)object_ident, sizeof(object_ident), 1, f1);
  265.   error |= !fwrite((char *)m_list, sizeof(m_list), 1, f1);
  266.   error |= !fwrite((char *)&mfptr, sizeof(mfptr), 1, f1);
  267.   error |= !fwrite((char *)&muptr, sizeof(muptr), 1, f1);
  268.   error |= !fwrite((char *)store, sizeof(store), 1, f1);
  269.  
  270.   if (stat(fnam, &buf) == -1)
  271.     {
  272.       (void) sprintf(temp, "Can not stat file %s", fnam);
  273.       msg_print(temp);
  274.       return;
  275.     }
  276.  
  277.   error |= !fwrite((char *)&buf, sizeof(buf), 1, f1);
  278.  
  279.   error |= !fwrite((char *)norm_state, sizeof(norm_state), 1, f1);
  280.   error |= !fwrite((char *)randes_state, sizeof(randes_state), 1, f1);
  281.   error |= !fwrite((char *)&randes_seed, sizeof(randes_seed), 1, f1);
  282.   error |= !fwrite((char *)town_state, sizeof(town_state), 1, f1);
  283.   error |= !fwrite((char *)&town_seed, sizeof(town_seed), 1, f1);
  284.  
  285.   /* this indicates 'cheating' if it is a one */
  286.   error |= !fwrite((char *)&panic_save, sizeof(panic_save), 1, f1);
  287.  
  288.   error |= fclose(f1);
  289.  
  290.   character_saved = 1;
  291.  
  292.   if (!wizard1)
  293.     if (chmod(fnam, 0) == -1)
  294.       {
  295.     (void) sprintf(temp, "Can not change file mode for %s", fnam);
  296.     msg_print(temp);
  297.     return;
  298.       }
  299.  
  300.   /* make sure user can't touch save file for 5 seconds */
  301.   (void) sleep(5);
  302.  
  303.   controlz();
  304.  
  305.   if (error)
  306.     {
  307.       (void) sprintf(temp, "Error writing to file %s", fnam);
  308.       prt(temp, 0, 0);
  309.       prt("Game not saved.", 0, 0);
  310.     }
  311.   else if (flag)
  312.     {
  313.       (void) sprintf(temp,"Character saved. [Moria Version %lf]",CUR_VERSION);
  314.       prt(temp, 0, 0);
  315.       if (exit)
  316.     exit_game();
  317.     }
  318. }
  319.  
  320.  
  321. get_char(fnam)
  322. char *fnam;
  323. {
  324.   register int i, j;
  325.   register FILE *f1;
  326.   int error;
  327.   vtype temp;
  328.   double version;
  329. #ifdef USG
  330.   struct stat buf, buf2;
  331. #else
  332.   struct stat lbuf, buf, buf2;
  333. #endif
  334.   char char_tmp;
  335.   char char_tmp_array[3];
  336.   register cave_type *c_ptr;
  337.   long age;
  338.  
  339.   clear_screen(0, 0);
  340.  
  341.   no_controlz();
  342.  
  343. #ifdef USG
  344.   /* no symbolic links */
  345.   if (stat(fnam, &buf) == -1)
  346. #else
  347.   if ((lstat(fnam, &lbuf) == -1) || (stat(fnam, &buf) == -1))
  348. #endif
  349.     {
  350.       (void) sprintf(temp, "Cannot stat file %s", fnam);
  351.       prt(temp, 0, 0);
  352.       exit_game();
  353.     }
  354.  
  355. #ifdef USG
  356.   /* no symbolic links */
  357. #else
  358.   if (lbuf.st_ino != buf.st_ino)
  359.     {
  360.       (void) sprintf(temp, "Cannot restore from symbolic link %s", fnam);
  361.       prt(temp, 0, 0);
  362.       exit_game();
  363.     }
  364. #endif
  365.  
  366.   if (buf.st_nlink != 1)
  367.     {
  368.       (void) sprintf(temp, "Too many links to file %s", fnam);
  369.       prt(temp, 0, 0);
  370.       exit_game();
  371.     }
  372.  
  373.   if (chmod(fnam, (IREAD | IWRITE)) == -1)
  374.     {
  375.       (void) sprintf(temp, "Can not change file mode for %s", fnam);
  376.       prt(temp, 0, 0);
  377.     }
  378.  
  379.   if ((f1 = fopen(fnam, "r")) == NULL)
  380.     {
  381.       (void) sprintf(temp, "Cannot open file %s for reading", fnam);
  382.       prt(temp, 0, 0);
  383.       exit_game();
  384.     }
  385.  
  386.   prt("Restoring Character...", 0, 0);
  387.   put_qio();
  388.   error = 0;
  389.   error |= !fread((char *)&version, sizeof(version), 1, f1);
  390.   error |= !fread((char *)&py, sizeof(py), 1, f1);
  391.   error |= !fread((char *)&char_row, sizeof(char_row), 1, f1);
  392.   error |= !fread((char *)&char_col, sizeof(char_col), 1, f1);
  393.   error |= !fread((char *)&inven_ctr, sizeof(inven_ctr), 1, f1);
  394.   error |= !fread((char *)&inven_weight, sizeof(inven_weight), 1, f1);
  395.   error |= !fread((char *)&equip_ctr, sizeof(equip_ctr), 1, f1);
  396.   error |= !fread((char *)&dun_level, sizeof(dun_level), 1, f1);
  397.   error |= !fread((char *)&missile_ctr, sizeof(missile_ctr), 1, f1);
  398.   error |= !fread((char *)&mon_tot_mult, sizeof(mon_tot_mult), 1, f1);
  399.   error |= !fread((char *)&turn, sizeof(turn), 1, f1);
  400.   error |= !fread((char *)inventory, sizeof(inventory), 1, f1);
  401.   error |= !fread((char *)magic_spell[py.misc.pclass],
  402.           sizeof(spell_type), 31, f1);
  403.   error |= !fread((char *)&cur_height, sizeof(cur_height), 1, f1);
  404.   error |= !fread((char *)&cur_width, sizeof(cur_width), 1, f1);
  405.   error |= !fread((char *)&max_panel_rows, sizeof(max_panel_rows), 1, f1);
  406.   error |= !fread((char *)&max_panel_cols, sizeof(max_panel_cols), 1, f1);
  407.  
  408.   for (i = 0; i < MAX_HEIGHT; i++)
  409.     for (j = 0; j < MAX_WIDTH; j++)
  410.       {
  411.     c_ptr = &cave[i][j];
  412.     error |= !fread((char *)&c_ptr->cptr, sizeof(c_ptr->cptr), 1, f1);
  413.     error |= !fread((char *)&c_ptr->tptr, sizeof(c_ptr->tptr), 1, f1);
  414.     error |= !fread((char *)&char_tmp, sizeof(char_tmp), 1, f1);
  415.     c_ptr->fval = char_tmp & 0xF;
  416.     c_ptr->fopen = (char_tmp >> 4) & 0x1;
  417.     c_ptr->fm = (char_tmp >> 5) & 0x1;
  418.     c_ptr->pl = (char_tmp >> 6) & 0x1;
  419.     c_ptr->tl = (char_tmp >> 7) & 0x1;
  420.       }
  421.  
  422.   error |= !fread((char *)t_list, sizeof(t_list), 1, f1);
  423.   error |= !fread((char *)&tcptr, sizeof(tcptr), 1, f1);
  424.   error |= !fread((char *)object_ident, sizeof(object_ident), 1, f1);
  425.   error |= !fread((char *)m_list, sizeof(m_list), 1, f1);
  426.   error |= !fread((char *)&mfptr, sizeof(mfptr), 1, f1);
  427.   error |= !fread((char *)&muptr, sizeof(muptr), 1, f1);
  428.  
  429.   if (version == 4.83)
  430.     {
  431.       /* insult_cur was a byte in 4.83, but is now a short */
  432.       for (i = 0; i < MAX_STORES; i++)
  433.     {
  434.       error |= !fread((char *)&store[i].store_open,
  435.              sizeof(short), 1, f1);
  436.       error |= !fread((char *)&char_tmp,
  437.              sizeof(char), 1, f1);   /* this is different */
  438.           store[i].insult_cur = (short)char_tmp;
  439.       error |= !fread((char *)&store[i].owner,
  440.              sizeof(char), 1, f1);
  441.       error |= !fread((char *)&store[i].store_ctr,
  442.              sizeof(char), 1, f1);
  443.           /* quick compatibility hack for a local vax */
  444.           /* ignore three bytes of fill character */
  445.       error |= !fread((char *)char_tmp_array,
  446.              sizeof(char), 3, f1);
  447.       error |= !fread((char *)store[i].store_inven,
  448.              sizeof(inven_record), STORE_INVEN_MAX, f1);
  449.     }
  450.     }
  451.   else
  452.     {
  453.       error |= !fread((char *)store, sizeof(store), 1, f1);
  454.     }
  455.  
  456.   error |= !fread((char *)&buf2, sizeof(buf2), 1, f1);
  457.  
  458.   error |= !fread((char *)norm_state, sizeof(norm_state), 1, f1);
  459.   error |= !fread((char *)randes_state, sizeof(randes_state), 1, f1);
  460.   error |= !fread((char *)&randes_seed, sizeof(randes_seed), 1, f1);
  461.   error |= !fread((char *)town_state, sizeof(town_state), 1, f1);
  462.   error |= !fread((char *)&town_seed, sizeof(town_seed), 1, f1);
  463.  
  464.   if (version >= 4.87)
  465.     {
  466.       error |= !fread((char *)&panic_save, sizeof(panic_save), 1, f1);
  467.     }
  468.  
  469.   error |= fclose(f1);
  470.  
  471.   controlz();
  472.  
  473.   if (buf.st_atime >= buf2.st_atime + 5)
  474.     {
  475.       (void) sprintf(temp, "File %s has been touched, sorry.", fnam);
  476.       prt(temp, 0, 0);
  477.       exit_game();
  478.     }
  479.  
  480.   if (error)
  481.     {
  482.       (void) sprintf(temp, "Error reading in file %s", fnam);
  483.       prt(temp, 0, 0);
  484.       exit_game();
  485.     }
  486.  
  487.   /* rotate store inventory, depending on how old the save file is */
  488.   /* foreach day or fraction thereof old, call store_maint once */
  489.   /* must do this before delete file */
  490.   if (stat (fnam, &buf2) == -1)
  491.     {
  492.       (void) sprintf(temp, "Cannot stat file %s?", fnam);
  493.       prt(temp, 0, 0);
  494.     }
  495.   else
  496.     {
  497.       age = (long)buf2.st_atime - (long)buf.st_atime;  /* age in seconds */
  498.       age = (age / 86400) + 1;  /* age in days */
  499.       for (i = 0; i < age; i++)
  500.     store_maint();
  501.     }
  502.  
  503.   if (unlink(fnam) == -1)
  504.     {
  505.       (void) sprintf(temp, "Cannot delete file %s", fnam);
  506.       prt(temp, 0, 0);
  507.       exit_game();
  508.     }
  509.  
  510.   if (panic_save == 1)
  511.     {
  512.       (void) sprintf(temp, "This game is from a panic save.  Score will not be added to scoreboard.");
  513.       msg_print (temp);
  514.       /* make sure player will see message before change_name is called */
  515.       msg_print (" ");
  516.     }
  517.  
  518.   /* reidentify objects */
  519.   /* very inefficient, should write new routine perhaps? */
  520.   for (i = 0; i < MAX_OBJECTS; i++)
  521.     if (object_ident[i] == TRUE)
  522.       identify(object_list[i]);
  523.  
  524.   /* in case restoring a dead character, this can happen if a signal
  525.      is caught after a characters hit points go below zero, but before
  526.      the game ends */
  527.   if (py.misc.chp <= -1)
  528.     {
  529.       prt("Your character has already died.", 23, 0);
  530.       (void) strcpy(died_from, "Unknown.");
  531.       death = 1;
  532.     }
  533.  
  534.   return(FALSE);
  535. }
  536.